package cn.shoukaiseki.sjf4j.jackson;

import cn.shoukaiseki.sjf4j.JsonException;
import cn.shoukaiseki.sjf4j.node.BaseTreeNode;
import cn.shoukaiseki.sjf4j.node.JsonNodeType;
import cn.shoukaiseki.sjf4j.node.NumberType;
import cn.shoukaiseki.sjf4j.node.TreeNode;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ValueNode;

import java.math.BigDecimal;
import java.util.Iterator;

public abstract class JacksonTreeNode<T extends JsonNode> extends BaseTreeNode {

    /**
     * 解析后的节点,存放Fastjson2或者jackson节点对象
     */
    protected T value;

    private JsonNodeType jsonNodeType;

    public JacksonTreeNode(T value){
       this.value = value;
        jsonNodeType=convertJsonNodeType(value.getNodeType());
    }

    @Override
    public JsonNodeType getNodeType() {
        return this.jsonNodeType;
    }

    public static TreeNode convert(JsonNode jsonNode){
        try{
            if (jsonNode instanceof ObjectNode) {
                return new JacksonObjectNode((ObjectNode) jsonNode);
            }
            if(jsonNode instanceof ArrayNode){
                return new JacksonArrayNode((ArrayNode)jsonNode);
            }
            if(jsonNode instanceof NullNode){
                return new JacksonNullNode((NullNode) jsonNode);
            }
            if(jsonNode instanceof ValueNode){
                return new JacksonValueNode((ValueNode) jsonNode);
            }
        } catch (Throwable t) {
            throw new JsonException(t);
        }
        throw new JsonException("转换不完善,jacksonNode类名 "+jsonNode.getClass());
    }

    public static JsonNodeType convertJsonNodeType(com.fasterxml.jackson.databind.node.JsonNodeType nodeType){
        if(com.fasterxml.jackson.databind.node.JsonNodeType.ARRAY==nodeType){
            return JsonNodeType.ARRAY;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.BINARY==nodeType){
            return JsonNodeType.BINARY;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.BOOLEAN==nodeType){
            return JsonNodeType.BOOLEAN;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.MISSING==nodeType){
            return JsonNodeType.MISSING;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.NULL==nodeType){
            return JsonNodeType.NULL;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.NUMBER==nodeType){
            return JsonNodeType.NUMBER;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.OBJECT==nodeType){
            return JsonNodeType.OBJECT;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.POJO==nodeType){
            return JsonNodeType.POJO;
        }
        if(com.fasterxml.jackson.databind.node.JsonNodeType.STRING==nodeType){
            return JsonNodeType.STRING;
        }
        throw new JsonException("未识别的jackson中的JsonNodeType");

    }

    public static NumberType convertNumberType(com.fasterxml.jackson.core.JsonParser.NumberType numberType){
        if(numberType ==null){return null;}
        if (com.fasterxml.jackson.core.JsonParser.NumberType.INT==numberType) {
           return NumberType.INT;
        }
        if (com.fasterxml.jackson.core.JsonParser.NumberType.LONG==numberType) {
            return NumberType.LONG;
        }
        if (com.fasterxml.jackson.core.JsonParser.NumberType.BIG_INTEGER==numberType) {
            return NumberType.BIG_INTEGER;
        }
        if (com.fasterxml.jackson.core.JsonParser.NumberType.FLOAT==numberType) {
            return NumberType.FLOAT;
        }
        if (com.fasterxml.jackson.core.JsonParser.NumberType.DOUBLE==numberType) {
            return NumberType.DOUBLE;
        }
        if (com.fasterxml.jackson.core.JsonParser.NumberType.BIG_DECIMAL==numberType) {
            return NumberType.BIG_DECIMAL;
        }
        throw new JsonException("未识别的jackson中的NumberType");
    }

    @Override
    public TreeNode get(String fieldName) {
        JsonNode jsonNode = value.get(fieldName);
        if(jsonNode==null){
            return null;
        }
        return convert(jsonNode);
    }

    @Override
    public TreeNode get(int index) {
        JsonNode jsonNode = value.get(index);
        if(jsonNode==null){
            return null;
        }
        return convert(jsonNode);
    }


    @Override
    public Iterator<String> fieldNames() {
        return value.fieldNames();
    }

    @Override
    public String toString() {
        return value.toString();
    }

    @Override
    public boolean isMissingNode() {
        return value.isMissingNode();
    }


    @Override
    public NumberType numberType() {
        JsonParser.NumberType numberType = value.numberType();
        return convertNumberType(numberType);
    }

    @Override
    public int size() {
        return value.size();
    }

    @Override
    public boolean isShort() {
        return value.isShort();
    }

    @Override
    public boolean canConvertToInt() {
        return value.canConvertToInt();
    }

    @Override
    public int asInt() {
        return value.asInt();
    }

    @Override
    public long asLong() {
        return value.asLong();
    }

    @Override
    public boolean asBoolean() {
        return value.asBoolean();
    }

    @Override
    public double asDouble() {
        return value.asDouble();
    }

    @Override
    public BigDecimal asDecimalVal() {
        return value.decimalValue();
    }
}
